package com.shiro.config;

import com.shiro.pojo.User;
import com.shiro.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

//自定义 UserRealm
public class UserRealm extends AuthorizingRealm {


    /*
        TODO 流程
        1、导入 shiro-spring pom 包 (shiro-spring整合依赖包)
        2、连接数据库  编写mapper方法
        3、自定义 UserRealm 继承 AuthorizingRealm     重写 (授权 | 认证) 方法
        4、创建ShiroConfig
            、创建 realm 对象 ,需要自定义
            、DefaultWebSecurityManager
            、ShiroFilterFactoryBean

         TODO shiro核心
            Subject 当前用户
            Shiro SecurityManager 管理所有的用户
            Realm 保证你的 Security数据

            subject:应用代码直接交互的对象是Subject,也就是说Shiro的对外API核心就是Subject, Subject代表了当前的用户,
                    这个用户不一定是一个具体的人,与当前应用交互的任何东西都是Subject,如网络爬虫,机器人等,与Subject的
                    所有交互都会委托给SecurityManager; Subject其实是一个门面,SecurityManageer才是实际的执行者

            SecurityManager:安全管理器,即所有与安全有关的操作都会与SercurityManager交互,并且它管理着所有的Subject,
                            可以看出它是Shiro的核心,它负责与Shiro的其他组件进行交互,它相当于SpringMVC的DispatcherServlet的角色

            Realm: Shiro从Realm获取安全数据(如用户,角色,权限) ,就是说SecurityManager要验证用户身份,那么它需要从
                    Realm获取相应的用户进行比较,来确定用户的身份是否合法:也需要从Realm得到用户相应的角色、权限,
                    进行验证用户的操作是否能够进行,可以把Realm看成DataSource;

     */

    @Autowired
    private UserService userService;


    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了 授权>=doGetAuthorizationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //进行授权
        //info.addStringPermission("user:add");
        //拿到当前登录对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser =(User) subject.getPrincipal();

        //设置数据库 用户存在的权限
        info.addStringPermission(currentUser.getPerms());

        // return info
        return info;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken Token) throws AuthenticationException {
        System.out.println("执行了 认证>=doGetAuthenticationInfo");
        //用户名 密码 ，数据中取出
//        String name="root";
//        String password="123456";
//        if(!userToken.getUsername().equals(name)){
//            return null; //自动抛出异常 UnknownAccountException
//        }
        UsernamePasswordToken userToken = (UsernamePasswordToken) Token;
        User user = userService.queryUserByName(userToken.getUsername());

        if(user==null){//如果没有这个人
            return null; //自动抛出异常 UnknownAccountException
        }

        //密码认证  shiro做~   密码加密了
        return new SimpleAuthenticationInfo(user,user.getPwd(),"");
    }
}
